package com.refusea.train.domain.helper

import com.refusea.train.config.mvc.WebSession
import com.refusea.train.domain.cache.UserCache
import com.refusea.train.domain.entity.Referrer
import com.refusea.train.domain.entity.ReferrerCommission.Cat.ORDER
import com.refusea.train.domain.entity.ReferrerCommission.Cat.SIGNUP
import com.refusea.train.domain.entity.User.Role.PRINCIPAL
import com.refusea.train.domain.entity.User.Role.REFERRER
import com.refusea.train.domain.ex.BizEx
import com.refusea.train.domain.req.ReferrerCommissionReq
import com.refusea.train.domain.vo.CommissionStatVo
import com.refusea.train.domain.vo.PaginationVo
import com.refusea.train.mapper.ReferrerCommissionMapper
import com.refusea.train.mapper.ReferrerMapper
import org.springframework.stereotype.Component
import java.time.LocalDate

/**
 * @author Zhang Yan 2024/4/23
 **/
@Component
class ReferrerHelper(
    private val referrerMapper: ReferrerMapper,
    private val referrerCommissionMapper: ReferrerCommissionMapper,
    private val userCache: UserCache,
) {
    private val limit = 10

    fun list(): List<Referrer> {
        return referrerMapper.list(WebSession.user().schoolId)
    }

    fun save(referrer: Referrer) {
        referrer.schoolId = WebSession.user().schoolId
        if (referrer.id == null || referrer.id == 0) {
            throw BizEx.of("参数错误，推广人 ID 为空")
        } else {
            referrerMapper.update(referrer)
        }
    }

    fun commissions(req: ReferrerCommissionReq): PaginationVo {
        val user = WebSession.user()
        if (user.role == REFERRER) {
            req.referrerId = user.id
        } else if (user.role != PRINCIPAL) {
            throw BizEx.BAD_REQUEST
        }
        req.schoolId = user.schoolId
        req.calculateOffset(limit)
        req.end = req.end?.plusDays(1)

        val total = referrerCommissionMapper.count(req)
        if (total == 0) {
            return PaginationVo.empty(req.page, limit)
        }

        return PaginationVo(
            req.page,
            limit,
            total,
            if (req.offset >= total) {
                emptyList()
            } else {
                val commissions = referrerCommissionMapper.query(req)
                commissions.forEach {
                    it.username = userCache.get(it.userId)?.name
                }
                commissions
            }
        )

    }

    fun delete(id: Int) {
        val user = WebSession.user()
        if (user.role != PRINCIPAL) {
            throw BizEx.of("权限不足")
        }
        referrerMapper.delete(user.schoolId, id)
    }

    fun pay(id: Int, date: LocalDate) {
        val user = WebSession.user()
        if (user.role != PRINCIPAL) {
            throw BizEx.of("权限不足")
        }
        referrerCommissionMapper.markPaid(user.schoolId, id, date)
    }

    fun stat(): CommissionStatVo {
        val user = WebSession.user()

        val stats = referrerCommissionMapper.stat(user.id)
        val lastPt = if (stats.any { it.paid && it.commission > 0 }) {
            referrerCommissionMapper.lastPt(user.id)
        } else {
            null
        }

        return CommissionStatVo(
            lastPt,
            stats.firstOrNull() { it.paid && it.cat == SIGNUP }?.commission ?: 0,
            stats.firstOrNull() { it.paid && it.cat == ORDER }?.commission ?: 0,
            stats.firstOrNull() { !it.paid && it.cat == SIGNUP }?.commission ?: 0,
            stats.firstOrNull() { !it.paid && it.cat == ORDER }?.commission ?: 0,
        )
    }
}
